﻿using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Documents;

namespace SocketServer
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private IPAddress MyIP { get; set; }
        private int Port { get; set; }
        private Thread ThreadAccept { get; set; }
        private TcpListener TcpListener { get; set; }
        private TcpClient TcpClient { get; set; } = new TcpClient();
        private NetworkStream NetworkStream { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            StopBtn.IsEnabled = false;
        }

        private void ListenBtn_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //for(int i = 50000; i < 60000; i++)
                //{
                //    bool isUsed = PortInUse(i);
                //    if (!isUsed)
                //    {
                //        Port = i;
                //        break;
                //    }
                //}

                //PortBox.Text = Port.ToString();

                MyIP = IPAddress.Parse(IpAddressBox.Text);
                Port = int.Parse(PortBox.Text);
                TcpListener = new TcpListener(MyIP, Port);
                TcpListener.ExclusiveAddressUse = false; //允许复用
                TcpListener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                TcpListener.Start();
                // 构造线程
                // TargetAccept自定义函数:接受客户端连接请求
                ThreadAccept = new Thread(new ThreadStart(TargetAccept));
                // 启动线程用于接受连接和接受数据
                ThreadAccept.Start();
                MessageInfo.Inlines.Add(new LineBreak());
                MessageInfo.Inlines.Add(new Run("启动监听成功"));
                ListenBtn.IsEnabled = false;
                StopBtn.IsEnabled = true;
            }
            catch (Exception ex)
            {
                MessageInfo.Inlines.Add(new LineBreak());
                MessageInfo.Inlines.Add(new Run("启动监听失败：" + ex.Message));
                StopBtn.IsEnabled = true;
            }
        }

        public bool PortInUse(int port)
        {
            bool inUse = false;

            IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
            IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();

            foreach (IPEndPoint endPoint in ipEndPoints)
            {
                if (endPoint.Port == port)
                {
                    inUse = true;
                    break;
                }
            }

            return inUse;
        }

        public void TargetAccept()
        {
            try
            {
                while (true)
                {
                    TcpClient = TcpListener.AcceptTcpClient();

                    Dispatcher.BeginInvoke(new Action(delegate
                    {
                        MessageInfo.Inlines.Add(new LineBreak());
                        MessageInfo.Inlines.Add(new Run("接收到客户端连接"));
                    }));

                    NetworkStream = TcpClient.GetStream();
                    byte[] byteArray = new byte[2048];

                    while (true)
                    {
                        if (TcpClient.Connected)
                        {
                            // 读取字节信息
                            int length = NetworkStream.Read(byteArray, 0, byteArray.Length);
                            string receiveMessage = Encoding.UTF8.GetString(byteArray, 0, length);

                            if (string.IsNullOrEmpty(receiveMessage))
                            {
                                StopTcpClient();
                                break;
                            }

                            Dispatcher.BeginInvoke(new Action(delegate
                            {
                                MessageInfo.Inlines.Add(new LineBreak());
                                MessageInfo.Inlines.Add(new Run("接收到客户端信息：" + receiveMessage));
                            }));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Dispatcher.BeginInvoke(new Action(delegate
                {
                    MessageInfo.Inlines.Add(new LineBreak());
                    MessageInfo.Inlines.Add(new Run("出错：" + ex.Message));
                }));
            }
        }

        private void StopBtn_Click(object sender, RoutedEventArgs e)
        {
            StopTcp();
        }

        private void StopTcp()
        {
            try
            {
                TcpListener.Stop();

                if (TcpClient.Connected)
                {
                    NetworkStream.Close();
                    TcpClient.Close();
                    TcpClient.Dispose();
                }

                Dispatcher.BeginInvoke(new Action(delegate
                {
                    ListenBtn.IsEnabled = true;
                    StopBtn.IsEnabled = false;
                }));
            }
            catch (Exception ex)
            {
                MessageInfo.Inlines.Add(new LineBreak());
                MessageInfo.Inlines.Add(new Run("关闭出错：" + ex.Message));
            }
        }

        private void StopTcpClient()
        {
            try
            {
                if (TcpClient.Connected)
                {
                    NetworkStream.Close();
                    TcpClient.Close();
                    TcpClient.Dispose();
                }
            }
            catch (Exception ex)
            {
                MessageInfo.Inlines.Add(new LineBreak());
                MessageInfo.Inlines.Add(new Run("关闭出错：" + ex.Message));
            }
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Environment.Exit(0);
        }

        private void 关闭_Click(object sender, RoutedEventArgs e)
        {
            Environment.Exit(0);
        }
    }
}
